package cz.muni.fi.hauntedhouses.dao.impl;

import cz.muni.fi.hauntedhouses.dao.HumanDAO;
import cz.muni.fi.hauntedhouses.entity.Human;
import cz.muni.fi.hauntedhouses.enums.Fear;
import cz.muni.fi.hauntedhouses.enums.Gender;
import cz.muni.fi.hauntedhouses.to.HouseTO;
import cz.muni.fi.hauntedhouses.to.HumanTO;
import cz.muni.fi.hauntedhouses.util.HumanUtil;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Repository;

/**
 *
 * @author Martin Vala, 359917
 */
@Repository
public class HumanDAOImpl implements HumanDAO {
    
    private EntityManager em;

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

    @Override
    public void create(HumanTO humanTo) {
        if (humanTo == null || humanTo.getId() != null) {
            throw new IllegalArgumentException("Human is null or human's ID is not null");
        }
        Human human = HumanUtil.TOToEntity(humanTo);
        
        this.em.persist(human);
        humanTo.setId(human.getId());
    }

    @Override
    public void update(HumanTO humanTo) {
        if (humanTo == null || humanTo.getId() == null || humanTo.getId() < 1) {
            throw new IllegalArgumentException("Human is null or wrong ID format");
        }
        Human human = HumanUtil.TOToEntity(humanTo);
        
        if (this.em.find(Human.class, human.getId()) == null) {
            throw new IllegalArgumentException("Given human not found");
        }
        this.em.merge(human);
    }

    @Override
    public void remove(HumanTO humanTo) {
        if (humanTo == null || humanTo.getId() == null || humanTo.getId() < 1) {
            throw new IllegalArgumentException("Human is null or wrong ID format");
        }
        
        Human h = this.em.find(Human.class, humanTo.getId());
        if (h == null) {
            throw new IllegalArgumentException("Given human not found");
        }
        this.em.remove(h);
    }

    @Override
    public HumanTO get(Long id) {
        if (id == null || id < 1) {
            throw new IllegalArgumentException("ID is null or wrong format");
        }
        Human human = this.em.find(Human.class, id);
        if (human == null) {
            throw new IllegalArgumentException("Human with given ID not found");
        }       
        HumanTO humanTo = HumanUtil.entityToTO(human);        
        return humanTo;
    }

    @Override
    public List<HumanTO> findAll() {
        TypedQuery<Human> query = this.em.createQuery("SELECT h FROM Human h", Human.class);
        List<Human> results = query.getResultList();
        if (results.isEmpty()) {
            return null;
        }
        
        return HumanUtil.listToDTO(results);
    }

    @Override
    public List<HumanTO> findByName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name is null");
        }
        
        TypedQuery<Human> query = this.em.createQuery("SELECT h FROM Human h WHERE name = :name", Human.class);
        List<Human> results = query.setParameter("name", name).getResultList();
        if (results.isEmpty()) {
            return null;
        }
        
        return HumanUtil.listToDTO(results);
    }

}
